package com.dnjn.happiness.biz.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dnjn.happiness.biz.domain.Communicate;
import com.dnjn.happiness.biz.domain.CommunicateRecordBean;
import com.dnjn.happiness.biz.domain.CommunicateVO;
import com.dnjn.happiness.biz.domain.vo.CommunicateBean;
import com.dnjn.happiness.biz.domain.vo.CommunicateTagsVO;
import com.dnjn.happiness.biz.domain.vo.StatisticalAnalysisVO;
import com.dnjn.happiness.biz.mapper.CommunicateMapper;
import com.dnjn.happiness.biz.service.ICommunicateService;
import com.dnjn.happiness.common.amqp.AmqpSender;
import com.dnjn.happiness.common.config.DateTimeFormatHolder;
import com.dnjn.happiness.common.core.constant.HappyConstants;
import com.dnjn.happiness.common.core.constant.SecurityConstants;
import com.dnjn.happiness.common.core.domain.R;
import com.dnjn.happiness.common.core.utils.DateUtils;
import com.dnjn.happiness.common.core.utils.StringUtils;
import com.dnjn.happiness.common.datascope.annotation.DataScope;
import com.dnjn.happiness.common.security.utils.SecurityUtils;
import com.dnjn.happiness.emo.api.RemoteEmoAvgScoreDailyService;
import com.dnjn.happiness.emo.api.RemoteEmoUserService;
import com.dnjn.happiness.emo.api.domain.EmoAvgScoreDaily;
import com.dnjn.happiness.emo.api.model.EmoUserVO;
import com.dnjn.happiness.common.core.score.vo.HappyCommunicate;
import com.dnjn.happiness.common.core.score.vo.HappyVO;
import com.dnjn.happiness.survey.api.enums.DimensionalityGrade;
import com.dnjn.happiness.system.api.RemoteConfigService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 沟通 服务实现类
 * </p>
 *
 * @author Amber
 * @since 2023-10-04
 */
@Service
public class CommunicateServiceImpl extends ServiceImpl<CommunicateMapper, Communicate> implements ICommunicateService {

    @Autowired
    CommunicateMapper communicateMapper;

    @Autowired
    private RemoteEmoUserService iUserService;

    @Autowired
    private RemoteConfigService configService;

    @Autowired
    private RemoteEmoAvgScoreDailyService dailyService;


    


    @Override
    public boolean handleScoreEvent(Long userId, Integer score) {

        /**todo
         * 查 临界值 判断小于 临界值
         * if 小于临界值
         *      查数据库有无记录
         *     有 更新
         *     无 新增
         *
         * */

        EmoUserVO one = null;
        R<EmoUserVO> result = iUserService.getInfoByUserId(userId, SecurityConstants.INNER);
        if (StringUtils.isNotNull(result) && StringUtils.isNotNull(result.getData())){
            one = result.getData();
        }
        if (null == one) {
            return true;
        }
        int num = 0;
        R<String> keyResult = configService.configKeyApi("biz.happinessScore.threshold", SecurityConstants.INNER);
        if(StringUtils.isNotNull(keyResult) && StringUtils.isNotNull(keyResult.getData())){
            num= Integer.parseInt(keyResult.getData());
        }

        if (null != one.getHappinessScore() && one.getHappinessScore() < num) {
            //同时落库沟通表,需沟通
            Long count = lambdaQuery().eq(Communicate::getUserId, userId).and((Wrappers) -> {
                Wrappers.eq(Communicate::getCommunicateStatus, "0").or().eq(Communicate::getCommunicateStatus, "1");
            }).count();
            if (count < 1) {
                Communicate communicate = new Communicate();
                communicate.setUserId(userId);
                communicate.setCommunicateType("INTERVIEW");
                communicate.setCommunicateStatus("0");
                saveCommunicate(communicate);
            }
        }
        return true;
    }


    @Override
    public int saveCommunicate(Communicate communicate) {
        return communicateMapper.insert(communicate);

    }

    @Override
    public void updateComSurvyId(Long surveyId, Long communicateId) {
        lambdaUpdate().eq(Communicate::getCommunicateId, communicateId).set(Communicate::getSurveyId, surveyId).update();
    }

    @Override
    public Communicate getCommunicateIdById(Long communicateId) {
        return communicateMapper.getCommunicateIdById(communicateId);
    }


    @Override
    @DataScope(deptAlias = "u")
    public Page<Communicate> queryComByUserId(Communicate domain, Page page) {
        return baseMapper.queryComByUserId(domain, page);
    }

    /**
     * 查询当前用户最近几天被沟通过
     *
     * @param userId
     * @return 近多少天被沟通过
     */
    @Override
    public Integer getCommunicateCount(Long userId) {
        return baseMapper.getCommunicateCount(userId);
    }

    @Override
    public Communicate getCommunicateByUserId(Long userId) {
        return baseMapper.getCommunicateByUserId(userId);
    }

    @Override
    public void getCountByUserId(List<CommunicateVO> records) {

        records.stream().forEach(communicateVO -> {
            Integer communicateCount = getCommunicateCount(communicateVO.getUserId());
            communicateVO.setCommunicateCount(communicateCount);
            if (null != communicateVO.getBirthday()) {

                Date birthday = communicateVO.getBirthday();
                Date now = DateUtils.getNowDate();
                int i = DateUtils.differentDaysByMillisecond(now, birthday);
                int year = i / 365;
                communicateVO.setBirthCountYear(year);
            }
            if (null != communicateVO.getEmpDate()) {
                Date empDate = communicateVO.getEmpDate();
                Date now = DateUtils.getNowDate();
                int i = DateUtils.differentDaysByMillisecond(now, empDate);

                communicateVO.setEmpDateCountDay(i);
            }


        });

    }

    @Override
    public Communicate getResult(Long userId, String lastTime, String scoreTime) {
        return baseMapper.getResult(userId, lastTime, scoreTime);
    }


    @Override
    public Page<StatisticalAnalysisVO> selectStatisticalAnalysisCommunicate(Integer count, String symbol, Integer likeCounts, String symbol1, Page page) {
        return baseMapper.selectStatisticalAnalysisCommunicate(count, symbol, likeCounts, symbol1, page);
    }

    @Override
    public Page<CommunicateVO> queryCommunicateTeam(Communicate domain, Page page) {
        return baseMapper.queryCommunicateTeam(domain, page);
    }


    //去指派
    @Override
    public int toAssignCommunicate(Communicate communicate) {
        return baseMapper.toAssign(communicate);
    }

    //填写沟通结果
    @Override
    public int editResultCommunicate(Communicate communicate) {
        communicate.setCommunicateStatus("3");
        return baseMapper.updateById(communicate);
    }

    @Override
    public Page<Communicate> getCommunicatePage(Page page, Communicate communicate) {
        return baseMapper.getCommunicatePage(page, communicate);
    }

    @Override
    public void deleteByStatus(String value) {
        baseMapper.deleteByStatus();
        if (ObjectUtils.isEmpty(value)) {
            return;
        }
        int num = Integer.parseInt(value);
//        List<User> userList = emoUserService.lambdaQuery().eq(User::getDeleted, "0").list();
        List<EmoUserVO> userList = new ArrayList<>();
        R<List<EmoUserVO>> result = iUserService.selectUserList(SecurityConstants.INNER);
        if (StringUtils.isNotNull(result) && StringUtils.isNotNull(result.getData())) {
            userList = result.getData();
        }
        if (null == userList || userList.size() == 0) {
            return;
        }
        for (EmoUserVO user : userList) {
            Integer happinessScore = user.getHappinessScore().intValue();
            //需要沟通
            if (happinessScore < num) {
                //同时落库沟通表,需沟通
                Long count = baseMapper.selectCount(Wrappers.lambdaQuery(Communicate.class).eq(Communicate::getUserId, user.getUserId()).and((Wrappers) -> {
                    Wrappers.eq(Communicate::getCommunicateStatus, "0").or().eq(Communicate::getCommunicateStatus, "1");
                }));
                if (count < 1) {
                    Communicate communicate = new Communicate();
                    communicate.setUserId(user.getUserId());
                    communicate.setCommunicateStatus("0");
                    baseMapper.insert(communicate);
                }
            }
        }
    }

    @Override
    public Page<Communicate> getPage(Page page, Communicate communicate) {
        return baseMapper.getPage(page, communicate);
    }

    @Override
    public List<Communicate> getCommunicatePageByFromUserId(Communicate communicate) {
        List<Long> userIdList = baseMapper.getWeekCommunicateUserIdList(communicate);
        Long fromUserId = communicate.getFromUserId();
        List<Communicate> list = new ArrayList<>();
        for (Long userId : userIdList) {
            list.add(baseMapper.getCommunicatePageByFromUserId(fromUserId, userId));
        }
        return list;
    }

    @Override
    public void getWeekScoreChange(List<Communicate> list) {
        DateTimeFormatter formatter = DateTimeFormatHolder.FORMATTER_YYYY_MM_DD_HH_MM_SS;
        //获取未来七天分值变化
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        for (Communicate record : list) {
            List<CommunicateRecordBean> scoreList = new ArrayList<>();
            scoreList.add(new CommunicateRecordBean().setLabel("初始快乐值").setValue(Objects.isNull(record.getHappyWhenCommunicating()) ? 0 : record.getHappyWhenCommunicating()));
            LocalDate scoreTime = null;
            if (StringUtils.isNotEmpty(record.getScoreTime())) {
                scoreTime = LocalDate.parse(record.getScoreTime(), formatter);
            } else {
                scoreTime = record.getCreateTime().toLocalDate();
            }
            for (int i = 1; i < 8; i++) {
                LocalDate localDate = scoreTime.plusDays(i);
                EmoAvgScoreDaily emoAvgScoreDaily = null;
                R<EmoAvgScoreDaily> result = dailyService.getEmoAvgScoreDailyByUserIdAndDate(record.getUserId(), localDate, SecurityConstants.INNER);
                if (StringUtils.isNotNull(result) && StringUtils.isNotNull(result.getData())){
                    emoAvgScoreDaily = result.getData();
                }                if (Objects.isNull(emoAvgScoreDaily)) {
                    scoreList.add(new CommunicateRecordBean().setLabel(i + "天").setValue(0));
                } else {
                    scoreList.add(new CommunicateRecordBean().setLabel(i + "天").setValue(emoAvgScoreDaily.getScoreAvg().setScale(0, BigDecimal.ROUND_HALF_UP).intValue()));
                }
            }
            record.setWeekScore(scoreList);
        }
    }

    @Override
    public List<Long> queryCommunicatRequired() {
        return baseMapper.queryCommunicatRequired();
    }

    @Override
    public List<Long> queryYesterdayyCommunicatRequired() {
        return baseMapper.queryYesterdayyCommunicatRequired();
    }

    @Override
    public List<Communicate> getByScoreTime(String dateNow, String yesterday) {
        return baseMapper.getByScoreTime(dateNow, yesterday);
    }

    @Override
    public void updateCommunicateWhenCommunicating(Long userId, String scoreTime, Integer happinessScores) {
        boolean update = lambdaUpdate()
                .eq(Communicate::getUserId, userId)
                .eq(Communicate::getScoreTime, scoreTime)
                .set(Communicate::getHappyWhenCommunicating, happinessScores).update();
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateResultCommunicate(Communicate communicate) {
        communicate.setOperUserId(SecurityUtils.getUserId());
        communicate.setCommunicateType("INTERVIEW");
        Long userId = communicate.getUserId();
        //所有人都可以沟通，通过grade 映射likeCounts
        communicate.setLikeCounts(DimensionalityGrade.getValue(communicate.getGrade()).getValue());
        EmoUserVO emoUser = null;
        R<EmoUserVO> result = iUserService.getInfoByUserId(userId, SecurityConstants.INNER);
        if (StringUtils.isNotNull(result) && StringUtils.isNotNull(result.getData())){
            emoUser = result.getData();
        }
        int num = 0;
        R<String> keyResult = configService.configKeyApi("biz.happinessScore.threshold", SecurityConstants.INNER);
        if(StringUtils.isNotNull(keyResult) && StringUtils.isNotNull(keyResult.getData())){
            num= Integer.parseInt(keyResult.getData());
        }
        SimpleDateFormat formatter = (SimpleDateFormat) DateTimeFormatHolder.DATE_FORMATTER_YYYY_MM_DD_HH_MM_SS;
        Date date = new Date(System.currentTimeMillis());
        communicate.setScoreTime(formatter.format(date));
        //沟通前改员工实际快乐值
        Long oldScore = emoUser.getHappinessScore();
        if (communicate.getCommunicateTagsJsonVOList().size() > 0) {
            communicate.setCommunicateTags(JSON.toJSONString(communicate.getCommunicateTagsJsonVOList()));
        }
        Communicate one = lambdaQuery().eq(Communicate::getUserId, userId).lt(Communicate::getCommunicateStatus, '3').one();
        if (null != one) {
            communicate.setHappyWhenCommunicating(oldScore.intValue());
            communicate.setCommunicateId(one.getCommunicateId());
            // todo 填写沟通结果得时候直接更新默认分还有结果分
            communicate.setCommunicateResultAddScore(communicate.getLikeCounts());
            communicate.setCommunicateDefult((int) (num - oldScore));
            editResultCommunicate(communicate);
            // todo mq
            HappyVO vo = new HappyVO();
            vo.setUserId(userId);
            HappyCommunicate happyCommunicate = new HappyCommunicate();
            happyCommunicate.setDefultAddScore(communicate.getCommunicateDefult().doubleValue());
            happyCommunicate.setResultAddScore(communicate.getCommunicateResultAddScore().doubleValue());
            vo.setRtype(HappyConstants.EMO_USER_RTYPE_COMM);
            vo.setCommunicate(happyCommunicate);

            AmqpSender.sendArgs(vo);

        } else {
            if (num <= oldScore) {
                communicate.setCommunicateStatus("3");
                communicate.setHappyWhenCommunicating(oldScore.intValue());
                baseMapper.insert(communicate);
                return;
            }
        }
    }


    @Override
    public List<CommunicateBean> queryCommunicateByUserId(Long userId) {
        Communicate dto = new Communicate();
        dto.setFromUserId(SecurityUtils.getUserId());
        dto.setUserId(userId);
        List<CommunicateBean> list = baseMapper.queryCommunicateByUserId(dto);
        for (CommunicateBean bean : list) {
            String communicateTags = bean.getCommunicateTags();
            if (StringUtils.isNotEmpty(communicateTags)) {
                JSONArray jsonArray = JSON.parseArray(communicateTags);
                List<CommunicateTagsVO> voList = JSON.parseArray(jsonArray.toJSONString(), CommunicateTagsVO.class);
                bean.setVoList(voList);
            }
        }

        return list;
    }

}
